﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Infragistics.Win.UltraWinGrid;
using Infragistics.Win;

namespace Billing.WindowsBase
{
    public partial class BaseList : FormBase
    {
        public List<Billing.IBaseObject> SelectedObjects = new List<Billing.IBaseObject>();

        #region Constructors
        public BaseList()
            : this(true)
        {
        }

        public BaseList(bool Register)
            : base(Register)
        {
            this.onBeforeInitialize();
            InitializeComponent();
            this.onAfterInitialize();
        }
        #endregion

        #region Event Declaration
        public event ChangedHandler GroupChanged;
        public event ChangedHandler ElementChanged;

        public event DoubleClickHandler GroupDoubleClick;
        public event DoubleClickHandler ElementDoubleClick;

        public event CountChangedHandler CountChanged;

        public event ImportingFileHandler ImportingFile;
        #endregion

        #region Private Declareation
        object oldValue;
        #endregion

        #region Public Properties
        private bool allowAdd = true, allowEdit = true, allowDelete = true, allowRefresh = true, allowSelect = false, allowExport = true, allowImport = false, allowSave = false, allowDataView = false;
        [RightAttributeExistence()]
        public bool AllowAdd
        {
            get { return allowAdd; }
            set
            {
                allowAdd = value;
                this.RefreshOperation();
            }
        }
        [RightAttributeExistence()]
        public bool AllowEdit
        {
            get { return allowEdit; }
            set
            {
                allowEdit = value;
                this.RefreshOperation();
            }
        }
        [RightAttributeExistence()]
        public bool AllowDelete
        {
            get { return allowDelete; }
            set
            {
                allowDelete = value;
                this.RefreshOperation();
            }
        }
        [RightAttributeExistence()]
        public bool AllowRefresh
        {
            get { return allowRefresh; }
            set
            {
                allowRefresh = value;
                this.RefreshOperation();
            }
        }
        [RightAttributeExistence()]
        public bool AllowSelect
        {
            get { return allowSelect; }
            set
            {
                allowSelect = value;
                this.RefreshOperation();
            }
        }
        [RightAttributeExistence()]
        public bool AllowExport
        {
            get { return allowExport; }
            set
            {
                allowExport = value;
                this.RefreshOperation();
            }
        }
        [RightAttributeExistence()]
        public bool AllowImport
        {
            get { return allowImport; }
            set
            {
                allowImport = value;
                this.RefreshOperation();
            }
        }
        [RightAttributeExistence()]
        public bool AllowSave
        {
            get { return allowSave; }
            set
            {
                allowSave = value;
                this.RefreshOperation();
            }
        }
        [RightAttributeExistence()]
        public bool AllowDataView
        {
            get { return allowDataView; }
            set
            {
                allowDataView = value;
                this.RefreshOperation();
            }
        }

        private string groupNameID;
        public string GroupNameID
        {
            get { return groupNameID; }
            set { groupNameID = value; }
        }

        private string groupNameKey;
        public string GroupNameKey
        {
            get { return groupNameKey; }
            set { groupNameKey = value; }
        }

        private string groupNameName;
        public string GroupNameName
        {
            get { return groupNameName; }
            set { groupNameName = value; }
        }

        private string elementNameID;
        public string ElementNameID
        {
            get { return elementNameID; }
            set { elementNameID = value; }
        }

        private string elementNameKey;
        public string ElementNameKey
        {
            get { return elementNameKey; }
            set { elementNameKey = value; }
        }

        private string elementNameName;
        public string ElementNameName
        {
            get { return elementNameName; }
            set { elementNameName = value; }
        }

        private SelectType mElementSelectType = SelectType.Single;

        public SelectType ElementSelectType
        {
            get { return mElementSelectType; }
            set
            {
                mElementSelectType = value;
                this.grd.DisplayLayout.Override.SelectTypeRow = value;
            }
        }




        bool panelTopVisible = true;
        bool panelBottomVisible = true;
        bool panelFullVisible = true;
        bool panelLeftVisible = true;

        [DefaultValue(true)]
        public bool PanelTopVisible
        {
            get
            { return panelTopVisible; }
            set
            {
                panelTopVisible = value;
                this.pnlTop.Visible = panelTopVisible;
            }
        }
        [DefaultValue(true)]
        public bool PanelBottomVisible
        {
            get
            { return panelBottomVisible; }
            set
            {
                panelBottomVisible = value;
                this.pnlBottom.Visible = panelBottomVisible;

            }
        }
        [DefaultValue(true)]
        public bool PanelFullVisible
        {
            get
            { return panelFullVisible; }
            set
            {
                panelFullVisible = value;
                this.pnlFull.Visible = panelFullVisible;
            }
        }
        [DefaultValue(true)]
        public bool PanelLeftVisible
        {
            get
            { return panelLeftVisible; }
            set
            {
                panelLeftVisible = value;
                this.pnlLeft.Visible = panelLeftVisible;
            }
        }

        private string mImportedFileName = string.Empty;
        [Browsable(false)]
        public string ImportedFileName
        {
            get { return mImportedFileName; }
            set { mImportedFileName = value; }
        }

        private string mExportedFileName = string.Empty;
        [Browsable(false)]
        public string ExportedFileName
        {
            get { return mExportedFileName; }
            set { mExportedFileName = value; }
        }

        private string mExportFilter = "Microsoft Excel|*.xls";

        public string ExportFilter
        {
            get { return mExportFilter; }
            set { mExportFilter = value; }
        }

        private string mImportFilter = "Microsoft Excel|*.xls";
        public string ImportFilter
        {
            get { return mImportFilter; }
            set { mImportFilter = value; }
        }

        bool mLoadData = true;

        [DefaultValue(true)]
        public bool LoadData
        {
            get
            { return mLoadData; }
            set
            {
                mLoadData = value;
            }
        }

        EditorType mEditorType = EditorType.GridRowEditor;
        [DefaultValue(EditorType.GridRowEditor)]
        public EditorType EditorType
        {
            get { return mEditorType; }
            set
            {
                mEditorType = value;
                this.RefreshOperation();
            }
        }


        #endregion

        #region Public Properties

        public int getCurrentGroupRowID
        {
            get
            {
                if (this.GroupNameID == string.Empty || this.GroupNameID == null)
                    throw new ArgumentNullException("GroupNameID");
                if (this.grdGroup.ActiveRow != null)
                    return (int)this.grdGroup.ActiveRow.Cells[this.GroupNameID].Value;
                else
                    return -1;
            }
        }
        public int getCurrentElementRowID
        {
            get
            {
                if (this.ElementNameID == string.Empty || this.ElementNameID == null)
                    throw new ArgumentNullException("ElementNameID");
                if (this.grd.ActiveRow != null)
                {
                    return Convert.ToInt32(this.grd.ActiveRow.Cells[this.ElementNameID].Value);
                }
                else
                    return -1;
            }
        }
        public UltraGridRowEditTemplate ElementRowTemplate
        {
            get { return this.grd.DisplayLayout.Bands[0].RowEditTemplate; }
            set { this.grd.DisplayLayout.Bands[0].RowEditTemplate = value; }
        }
        public string SaveButtonText
        {
            get { return this.btnSave.Text; }
            set { this.btnSave.Text = value; }
        }
        public int SaveButtonWidth
        {
            get { return this.btnSave.Width; }
            set { this.btnSave.Width = value; }
        }
        #endregion

        #region Virtual Methods
        protected virtual void onAdd()
        {
            this.onEditorOpen(eOpenMode.New);
        }
        protected virtual void onEdit()
        {
            this.onEditorOpen(eOpenMode.Edit);
        }
        protected virtual void onDelete()
        {
        }
        protected virtual void onClose()
        {
            this.Close();
        }
        protected virtual void onSave()
        {

        }
        protected virtual void onRefresh()
        { this.onDataLoad(); }
        protected virtual void onSelect()
        {
            this.SelectObjects();
            this.DialogResult = DialogResult.OK;
            this.Close();
        }

        protected virtual void onExport(UltraGrid grd)
        {
            try
            {
                SaveFileDialog sfd = new SaveFileDialog();
                sfd.Filter = this.ExportFilter;
                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    this.ExportedFileName = sfd.FileName;
                    if (grd != null)
                    {
                        this.gee.Export(grd, this.ExportedFileName);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        protected virtual void onImport()
        {
            try
            {
                OpenFileDialog ofd = new OpenFileDialog();
                ofd.Filter = this.ImportFilter;
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    this.ImportedFileName = ofd.FileName;
                    if (this.ImportingFile != null)
                        this.ImportingFile(ofd.FileName);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        protected virtual void onEditorOpen(eOpenMode OpenMode)
        {
        }
        protected virtual void onDataLoad()
        { }
        protected virtual void onDataView()
        { }
        protected virtual void onElemetnDoubleClick()
        {
            if (this.AllowSelect)
                this.onSelect();
            else
                this.onEditorOpen(eOpenMode.Edit);
        }
        protected virtual void onGroupDoubleClick()
        {
        }
        protected virtual void onElementInitializeLayout(object sender, Infragistics.Win.UltraWinGrid.InitializeLayoutEventArgs e)
        {
            e.Layout.Override.ActiveRowAppearance.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(251)))), ((int)(((byte)(230)))), ((int)(((byte)(148)))));
            e.Layout.Override.ActiveRowAppearance.BackColor2 = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(149)))), ((int)(((byte)(21)))));
            e.Layout.Override.ActiveRowAppearance.BackGradientStyle = Infragistics.Win.GradientStyle.Vertical;
            e.Layout.Override.ActiveRowAppearance.ForeColor = System.Drawing.Color.DarkBlue;
            if (mEditorType == EditorType.Manual)
                e.Layout.Override.CellClickAction = Infragistics.Win.UltraWinGrid.CellClickAction.RowSelect;
            else
                e.Layout.Override.CellClickAction = CellClickAction.Default;
        }
        protected virtual void onGroupInitializeLayout(object sender, Infragistics.Win.UltraWinGrid.InitializeLayoutEventArgs e)
        {
            e.Layout.Override.ActiveRowAppearance.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(251)))), ((int)(((byte)(230)))), ((int)(((byte)(148)))));
            e.Layout.Override.ActiveRowAppearance.BackColor2 = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(149)))), ((int)(((byte)(21)))));
            e.Layout.Override.ActiveRowAppearance.BackGradientStyle = Infragistics.Win.GradientStyle.Vertical;
            e.Layout.Override.ActiveRowAppearance.ForeColor = System.Drawing.Color.DarkBlue;
            e.Layout.Override.CellClickAction = Infragistics.Win.UltraWinGrid.CellClickAction.RowSelect;
        }
        protected virtual void onBeforeInitialize()
        { }
        protected virtual void onAfterInitialize()
        { }
        #endregion

        #region Button Events
        private void btnAdd_Click(object sender, EventArgs e)
        {
#if DEBUG
            try
            {
#endif
                this.onAdd();
#if DEBUG
            }
            catch (Exception x)
            {
                MessageBox.Show(x.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
#endif
        }

        private void btnEdit_Click(object sender, EventArgs e)
        {
#if DEBUG
            try
            {
#endif
                this.onEdit();
#if DEBUG
            }
            catch (Exception x)
            {
                MessageBox.Show(x.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
#endif
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("გსურთ მონაცემის წაშლა?", "წაშლა", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
            {
                this.onDelete();
            }
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.onClose();
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
#if DEBUG
            try
            {
#endif
                this.Refresh();
#if DEBUG
            }
            catch (Exception x)
            {
                MessageBox.Show(x.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
#endif
        }

        private void btnSelect_Click(object sender, EventArgs e)
        {
#if DEBUG
            try
            {
#endif
                this.onSelect();
#if DEBUG
            }
            catch (Exception x)
            {
                MessageBox.Show(x.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
#endif

        }

        private void btnExport_Click(object sender, EventArgs e)
        {
#if DEBUG
            try
            {
#endif

                this.onExport(this.grd);
#if DEBUG
            }
            catch (Exception x)
            {
                MessageBox.Show(x.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
#endif
        }

        private void btnImport_Click(object sender, EventArgs e)
        {
#if DEBUG
            try
            {
#endif
                this.onImport();
#if DEBUG
            }
            catch (Exception x)
            {
                MessageBox.Show(x.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
#endif
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
#if DEBUG
            try
            {
#endif
                this.Save();
#if DEBUG
            }
            catch (Exception x)
            {
                MessageBox.Show(x.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
#endif
        }

        private void btnDataView_Click(object sender, EventArgs e)
        {
#if DEBUG
            try
            {
#endif
                this.onDataView();
#if DEBUG
            }
            catch (Exception x)
            {
                MessageBox.Show(x.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
#endif
        }
        #endregion

        #region Private Methods
        private void RefreshOperation()
        {
            switch (mEditorType)
            {
                case EditorType.Manual:
                    {
                        this.btnAdd.Visible = this.allowAdd;
                        this.btnEdit.Visible = this.allowEdit;
                        this.grd.DisplayLayout.Override.AllowAddNew = Infragistics.Win.UltraWinGrid.AllowAddNew.No;
                        this.grd.DisplayLayout.Override.AllowUpdate = Infragistics.Win.DefaultableBoolean.False;
                        this.grd.DisplayLayout.Override.AllowDelete = Infragistics.Win.DefaultableBoolean.False;
                        break;
                    }
                case EditorType.GridRowEditor:
                    {
                        this.grd.DisplayLayout.Override.AllowAddNew = (this.allowAdd ? AllowAddNew.TemplateOnBottom : AllowAddNew.No);
                        this.grd.DisplayLayout.Override.AllowUpdate = (this.allowEdit ? DefaultableBoolean.True : DefaultableBoolean.False);
                        this.grd.DisplayLayout.Override.AllowDelete = (this.allowDelete ? DefaultableBoolean.True : DefaultableBoolean.False);
                        this.btnAdd.Visible = false;
                        this.btnEdit.Visible = false;
                        break;
                    }
            }

            this.btnDelete.Visible = this.allowDelete;
            this.btnRefresh.Visible = this.allowRefresh;
            this.btnSelect.Visible = this.allowSelect;
            this.btnExport.Visible = this.allowExport;
            this.btnImport.Visible = this.allowImport;
            this.btnSave.Visible = this.allowSave;
            this.btnDataView.Visible = this.allowDataView;
        }

        private void RefreshStatusBar()
        {

        }

        #endregion

        #region Public Methods

        public void SelectObjects()
        {
            try
            {
                SelectedObjects.Clear();
                if (this.bsElement.Current != null)
                {
                    if (grd.Selected.Rows.Count <= 1)
                    {
                        SelectedObjects.Add((IBaseObject)this.bsElement.Current);
                    }
                    else
                        if (grd.Selected.Rows.Count != 0)
                        {
                            foreach (UltraGridRow var in grd.Selected.Rows)
                            {
                                if (var.ListObject is System.Data.DataRowView)
                                {
                                    SelectedObjects.Add((IBaseObject)((System.Data.DataRowView)var.ListObject).Row);
                                }
                                else
                                {
                                    SelectedObjects.Add((IBaseObject)var.ListObject);
                                }
                            }
                        }
                        else
                        {
                            SelectedObjects.Add((IBaseObject)this.bsElement.Current);
                        }
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        public void Save()
        {
            this.Cursor = Cursors.WaitCursor;
            this.onSave();
            this.Cursor = Cursors.Arrow;
        }
        public override void Refresh()
        {
            base.Refresh();
            this.Cursor = Cursors.WaitCursor;
            this.onRefresh();
            this.Cursor = Cursors.Arrow;
        }

        #endregion

        #region Grid Events
        private void grdGroup_AfterSelectChange(object sender, Infragistics.Win.UltraWinGrid.AfterSelectChangeEventArgs e)
        {

        }

        private void grd_InitializeLayout(object sender, InitializeLayoutEventArgs e)
        {
            this.onElementInitializeLayout(sender, e);
        }

        #region Grid Row DoubleClick Event
        UltraGridRow PupUpRow;
        System.Collections.BitArray GridEvents = new System.Collections.BitArray(2, false);

        public enum GridElements
        {
            Row,
            GroupBox
        }

        private void Grid_MouseEnterElement(object sender, Infragistics.Win.UIElementEventArgs e)
        {
            try
            {
                if (e.Element is CellUIElement || e.Element is RowSelectorUIElement)
                {
                    this.SetGridEventValue(GridElements.Row, true);
                    if (e.Element is CellUIElement)
                        PupUpRow = ((CellUIElement)e.Element).Row;
                    else if (e.Element is RowSelectorUIElement)
                        PupUpRow = ((RowSelectorUIElement)e.Element).Row;
                }
                else if (e.Element is GroupByBoxUIElement)
                    this.SetGridEventValue(GridElements.GroupBox, true);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.StackTrace);
            }
        }

        private void Grid_MouseLeaveElement(object sender, Infragistics.Win.UIElementEventArgs e)
        {
            try
            {
                if (e.Element is CellUIElement || e.Element is RowSelectorUIElement)
                {
                    this.SetGridEventValue(GridElements.Row, false);
                    PupUpRow = null;
                }
                else if (e.Element is GroupByBoxUIElement)
                    this.SetGridEventValue(GridElements.GroupBox, false);
            }
            catch (Exception ex)
            { MessageBox.Show(ex.StackTrace); }

        }

        private void Grid_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            try
            {
                switch (e.Button)
                {
                    case MouseButtons.Left:
                        if (e.Clicks == 2 && this.GetGridEventValue(GridElements.Row))
                        {
                            if (sender.GetHashCode() == this.grd.GetHashCode())
                            {
                                if (this.ElementDoubleClick != null)
                                    this.ElementDoubleClick(this.getCurrentElementRowID);
                                this.onElemetnDoubleClick();
                            }
                            if (sender.GetHashCode() == this.grdGroup.GetHashCode())
                            {
                                if (this.GroupDoubleClick != null)
                                    this.GroupDoubleClick(this.getCurrentGroupRowID);
                                this.onGroupDoubleClick();
                            }
                        }
                        else if (e.Clicks == 2 && this.GetGridEventValue(GridElements.GroupBox))
                            this.grd.ShowColumnChooser(true);
                        break;
                    case MouseButtons.Middle:
                        break;
                    case MouseButtons.None:
                        break;
                    case MouseButtons.Right:
                        if (e.Clicks == 1 && this.GetGridEventValue(GridElements.Row))
                            if (PupUpRow != null)
                            {
                                PupUpRow.Activate();
                                PupUpRow.Selected = true;
                            }
                        break;
                    case MouseButtons.XButton1:
                        break;
                    case MouseButtons.XButton2:
                        break;
                    default:
                        break;
                }
            }
            catch (Exception ex)
            { MessageBox.Show(ex.Message); }
        }

        private void SetGridEventValue(GridElements GridEvent, bool Value)
        { this.GridEvents[(int)GridEvent] = Value; }

        private bool GetGridEventValue(GridElements Gridevent)
        { return this.GridEvents[(int)Gridevent]; }

        #endregion
        #endregion

        #region Overrides
        protected override void OnLoad(EventArgs e)
        {
            this.RefreshOperation();
            base.OnLoad(e);
            if (this.LoadData)
                this.onDataLoad();
        }
        #endregion

        private void grdGroup_AfterRowActivate(object sender, EventArgs e)
        {
            if (this.GroupChanged != null)
                this.GroupChanged(this.getCurrentGroupRowID);
        }

        private void grdGroup_InitializeLayout(object sender, InitializeLayoutEventArgs e)
        {
            this.onGroupInitializeLayout(sender, e);
        }

        public override void PrepareForSelectDialogStyle()
        {
            base.PrepareForSelectDialogStyle();
            this.PanelTopVisible = false;
            this.AllowAdd = false;
            this.AllowDelete = false;
            this.AllowDrop = false;
            this.AllowSave = false;
            this.AllowExport = false;
            this.AllowEdit = false;
            this.AllowSelect = true;
            this.ShowInTaskbar = false;
        }
    }

    #region Delegates
    public delegate void ChangedHandler(int ID);
    public delegate void DoubleClickHandler(int ID);
    public delegate void CountChangedHandler(int Count, eObjectType ObjectType);
    public delegate void ImportingFileHandler(string FileName);
    #endregion

    public enum eObjectType
    {
        Group,
        Element
    }

    public enum EditorType
    {
        Manual,
        GridRowEditor
    }
}
